﻿using S7.Net;
using S7.Net.Types;
using Sunny.UI;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace S7NetPlusDemo2
{
    public partial class Form1 : UIForm
    {
        #region 定义变量
        volatile Plc plc;
        CancellationTokenSource cts = new CancellationTokenSource();
        volatile string isConnetionIng = "0";
        #endregion

        public Form1()
        {
            InitializeComponent();
            InitParameter();
        }

        /// <summary>
        ///  初始化参数
        /// </summary>
        private void InitParameter()
        {
            ComBox_Type.DataSource = Enum.GetValues(typeof(VarType));
            ComBox_CpuType.DataSource = Enum.GetValues(typeof(CpuType));
        }

        #region 按钮触发事件

        private void Btn_Con_Click(object sender, System.EventArgs e)
        {
            if (isConnetionIng.Equals("1"))
            {
                MessageBox.Show("正在进行连接，请勿重复点击");
                return;
            }
            Task.Run(() =>
            {
                lock (isConnetionIng)
                {
                    if (isConnetionIng.Equals("1"))
                    {
                        MessageBox.Show("正在进行连接，请勿重复点击");
                        return;
                    }
                    isConnetionIng = "1";
                    if (plc != null && plc.IsConnected)
                    {
                        MessageBox.Show("plc已连接");
                        isConnetionIng = "0";
                        return;
                    }
                    CpuType cpuType = (CpuType)Enum.Parse(typeof(CpuType), ComBox_CpuType.Text);
                    string ip = TxtBox_Ip.Text;
                    plc = new Plc(cpuType, ip, 0, 0);
                    try
                    {
                        plc.Open();
                        MessageBox.Show("连接成功");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("连接失败：" + ex.Message);
                    }
                    finally
                    {
                        isConnetionIng = "0";
                    }
                }
            });
        }

        private void Btn_Read_Click(object sender, EventArgs e)
        {
            if (plc == null || !plc.IsConnected)
            {
                MessageBox.Show("plc未连接");
                return;
            }
            if (cts.IsCancellationRequested)
            {
                return;
            }
            int db = int.Parse(ComBox_DB.Text);
            int startByteAdr = int.Parse(ComBox_Offet.Text);
            VarType varType = (VarType)Enum.Parse(typeof(VarType), ComBox_Type.Text);
            int varCount = int.Parse(ComBox_Num.Text);
            try
            {

                Task.Run(() =>
                {
                    while (true)
                    {
                        TxtBox_Val.Text = plc.Read(DataType.DataBlock, db, startByteAdr, varType, varCount)?.ToString() ?? "";
                        Thread.Sleep(1000);
                    }
                }, cts.Token);
            }
            catch (Exception ex)
            {
                MessageBox.Show("出现异常了：" + ex.Message);
            }
        }

        private void Btn_Write_Click(object sender, EventArgs e)
        {
            if (plc == null || !plc.IsConnected)
            {
                MessageBox.Show("plc未连接");
                return;
            }
            int db = int.Parse(ComBox_DB.Text);
            int startByteAdr = int.Parse(ComBox_Offet.Text);
            object val = GetObjVal();
            try
            {
                plc.Write(DataType.DataBlock, db, startByteAdr, val);
                MessageBox.Show("写入成功");
            }
            catch (Exception ex)
            {
                MessageBox.Show("出现异常了：" + ex.Message);
            }
        }
        #endregion

        /// <summary>
        /// string转我需要的类型， 例如int，再转为object并返回
        /// </summary>
        /// <returns></returns>
        private object GetObjVal()
        {
            string valStr = TxtBox_Val.Text;
            VarType varType = (VarType)Enum.Parse(typeof(VarType), ComBox_Type.Text);
            Object valObj = valStr;
            switch (varType)
            {
                case VarType.Real:
                    valObj = float.Parse(valStr);
                    break;
                case VarType.Word:
                    valObj = ushort.Parse(valStr);
                    break;
                default: break;
            }
            return valObj;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                cts.Cancel();
                if (plc != null && plc.IsConnected)
                {
                    plc.Close();
                }
                Dispose();
            }
            catch
            {
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
        }
    }
}
